import { FC, ReactElement, useContext, useEffect, useLayoutEffect, useRef } from "react";

import { KeepAliveContext } from "./KeepAliveScope.tsx";

interface KeepAliveItemProps {
	children: ReactElement;
	cacheId: string;
}

const KeepAlive: FC<KeepAliveItemProps> = props => {
	const { children, cacheId } = props;
	const { cacheDispatch, hasAliveStatus } = useContext(KeepAliveContext) ?? {};
	const parentNode = useRef<HTMLDivElement | null>(null);
	const isMount = useRef(false);
	const loadElement = (currentNode: HTMLDivElement) => {
		parentNode.current && parentNode.current.append(currentNode);
	};

	useEffect(() => {
		isMount.current = true;
		cacheDispatch!({
			action: "ACTION_ACTIVE",
			payload: {
				cacheId,
				loadElement
			}
		});
		return () => {
			cacheDispatch!({
				action: "ACTION_UNACTIVE",
				payload: {
					cacheId
				}
			});
		};
	}, [cacheDispatch, cacheId]);

	useLayoutEffect(() => {
		!isMount.current &&
			!hasAliveStatus!(cacheId).isKeep &&
			cacheDispatch!({
				action: "ACTION_CREATE",
				payload: {
					cacheId,
					loadElement,
					children
				}
			});
		// 更新缓存
		isMount.current &&
			hasAliveStatus!(cacheId).status !== "unActive" &&
			cacheDispatch!({
				action: "ACTION_UPDATE",
				payload: {
					cacheId,
					children: children
				}
			});
	}, [cacheDispatch, cacheId, children, hasAliveStatus]);

	return <div ref={parentNode} />;
};

export default KeepAlive;
